package tools;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;

import tools.shapes.Shape;
import app.DrawingCanvas;


/**
 * Select can be used to modify existing shapes on the canvas
 * 
 *	The select tool is able to modify the active object of the canvas
 *	It can be used to resize existing objects, or move existing objects
 */
public class SelectTool extends Tool {
   
  /* Class member variables */
  protected DrawingCanvas canvas;
  protected Point startingMousePosition;

  protected boolean modify;
  protected boolean corner;
  protected Color saveColor;

  /****< Constructor >*********************************************************/
  public SelectTool(DrawingCanvas c) {
    if( c != null )
      canvas = c;
    else
      throw new IllegalArgumentException();
  }
  
  /****< Draw Method >*********************************************************/
  protected void drawLineSegment(Point p1, Point p2) {
    canvas.getimageBufferGraphics().drawLine(p1.x,p1.y,
				           p2.x, p2.y);
    /* redraw only the small rectangle  */
    /* containing the new line segment  */
    int x0 = Math.min(p1.x, p2.x);
    int y0 = Math.min(p1.y, p2.y);
    int dx = Math.abs(p2.x - p1.x)+ 1;
    int dy = Math.abs(p2.y - p1.y) + 1;
    canvas.repaint(x0, y0, dx, dy);
  }

  /****< Event Handlers >******************************************************/
  /* (non-Javadoc)
   * 
   * Establish starting point for next drawing.
   * 
   * @see tools.Tool#mousePressed(java.awt.event.MouseEvent)
   */
  public void mousePressed(MouseEvent e)  {    
    startingMousePosition = e.getPoint();

    selectionCheck(); /* determines if an action is allowed on next mouse click */
	
/*	The following contains the activation sequence for a mouse pressed event
 *  only need to perform the following operations if it can modify something */

    if( modify || corner ){

	/* get starting mouse position */
	    startingMousePosition = e.getPoint();
	//    currentMousePosition = startingMousePosition;
	    Graphics iBGraphics = canvas.getimageBufferGraphics();
	    saveColor = iBGraphics.getColor( );
	    iBGraphics.setXORMode(Color.lightGray);
	    iBGraphics.setColor(Color.white);
	    Shape activeObject = canvas.getActiveObject();
	    activeObject.draw( canvas );

	    canvas.repaint();
    }
		
  }

  /* Selection Check
 	*
 	* Evaluates if the selected point was within a bounding box or not
 	* Determines what course of action to take
 	*
 	****/

  protected void selectionCheck() {

	Shape activeObject = canvas.getActiveObject();
  /* determine if the point is on the corner of the object bounding box */
	if((activeObject != null)&&(activeObject.onCorner(startingMousePosition))){
		corner = true;
  	}  /* determine if the point is within the active object bounding box */ 
	else if((activeObject != null)&&(activeObject.insideBoundingBox(startingMousePosition))){
		corner = false;
		modify = true;
	}  /* the active object should no longer be active */
	else{
		/* the object should not be modifyable on first click */
		modify = false;
		corner = false;
		/* the active object should be temporarily set to null */
		if (canvas.getActiveObject() != null) {
			canvas.getActiveObject().drawBoundingBox(canvas.getimageBufferGraphics());
		}
		canvas.setActiveObject(null);
		/* use some iterator to loop through the canvas object vector */
		
		int vectorLength = canvas.getShapeStack().size();
		for(int count = vectorLength - 1; (canvas.getActiveObject() == null) && (count >= 0); count--){
			/* at this point need a vector operation to pop a new object into context */
			Shape object = canvas.getShape(count);
			if(object.insideBoundingBox(startingMousePosition)){
				canvas.setActiveObject( object );
			}
		}
		if(canvas.getActiveObject() != null) {
			canvas.getActiveObject().drawBoundingBox(canvas.getimageBufferGraphics());
		}
	}
  }

  /* (non-Javadoc)
   * 
   * Can perform several actions dependent on startingMousePosition
   *  If modify isn't set this function doesn't do anything
   *  If modify is set then it will launch the object draw method with
   *  relevant information.  Eventually launches resize and move
   * 
   * @see tools.Tool#mouseDragged(java.awt.event.MouseEvent)
   */
  public void mouseDragged(MouseEvent e)  {

	/* If a new object was selected
	* the value of modify should be 1
	* if modify is 0 return without further modification
	****/ 

    	Point newMousePosition = e.getPoint();

	/*
	* If the corner status is set then the drag operation should
	* be a resize operation, pass the relevant parameters
	* otherwise if modify is set, it should simply move the object
	* pass the relevant parameters
	*/

    	Shape activeObject = canvas.getActiveObject();
    
	if( corner ){

		activeObject.draw(canvas);
		activeObject.resize(startingMousePosition, newMousePosition);
		activeObject.draw(canvas);
		canvas.repaint();
	}
	else if( modify ){
		activeObject.draw(canvas);
		activeObject.move(startingMousePosition, newMousePosition);
		activeObject.draw(canvas);
		canvas.repaint();
	}

	/* resets starting mouse position for next relative move or resize op */
	startingMousePosition = newMousePosition;
   
  }

  public void mouseReleased(MouseEvent e) {
	
      Graphics iBGraphics = canvas.getimageBufferGraphics();

	  Shape shape = canvas.getActiveObject();
	  
	    /* Erase final temporary figure  */
	    if (shape != null) {
	    	shape.draw( canvas );
	    }	    
	    /* Return graphics context to normal drawing mode and color */
	    iBGraphics.setPaintMode();
	    iBGraphics.setColor(saveColor);
	    	    
	    /* Draw final"permanent" figure */
	    if (shape != null) {
	    	shape.draw( canvas );
	    }
	   

	    canvas.redrawAll(); 
	  
  }
  
  public void mouseClicked(MouseEvent e) {
	  startingMousePosition = e.getPoint();
	  selectionCheck();
	  canvas.repaint();
  }
}// end public class SelectTool extends Tool

